﻿//Author:Michal Sporna
//License: https://operationsneakpeek.codeplex.com/license

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace World
{
    /// <summary>
    /// Handles bomb scanning process
    /// </summary>
    public static class ScannerManager
    {
        #region properties
        public static bool ChoosingNodes;
        public static List<Classes.ScannerNode> ScannerNodes;
        public static bool IsScanning;
        public static int Energy;//actual energy value that is taken from user only when node is scanned and uncovered
        public static int EnergyEstimate; //energy estimate is used when choosing nodes to scan, to show how much energy will be taken from user when scanning
        public static int BatteryLevel; //auto scanner battery level
        public static double BatteryLevelRefillTime; //start of time counter to the next refill
        public static double ScannerElapsedTime;
        public static int CurrentScannedNodeID;
        public static bool Phase1DoneForCurrentID;
        public static bool Phase2DoneForCurrentID;
        public static bool EndScanning;
        public static bool CurrentNodeHasBomb;
        public static bool UncoverBombAnimationInProgress;
        public static int UncoverBombAnimationFrame;
        public static double UncoverBombAnimationTime;
        public static Util.Classes.BombToDraw BombToDrawInstance;
        public static bool AtLeastOneNodeIsSelected;
        public static bool ScanButtonPrepared;
        public static Rectangle ScanButtonRectangle;
        public static bool RedPointerPointingScanButtonShown;
        public static Rectangle RedPointerRectangle;
        public static int RedPointerDirection;
        public static double RedPointerTimeOn;
        public static double RedPointerTimeOff;

        //letter
        public static bool CurrentNodeHasLetter;
        public static bool UncoverLetterAnimationInProgress;
        public static int UncoverLetterAnimationFrame;
        public static double UncoverLetterAnimationTime;
        public static Classes.Letter LetterInstance;




        public static bool ChoosingNodesModePending;

        #region TEXTURES
        private static bool _NodesTexturesSet;
        private static Texture2D _VeryHotTexture;
        private static Texture2D _HotTexture;
        private static Texture2D _WarmTexture;
        private static Texture2D _ColdTexture;
        private static Texture2D _VeryColdTexture;


        #endregion

        #region AUTO SCANNER
        public static bool AutoScannerON;

        #endregion
        #endregion


        #region METHODS

        /// <summary>
        /// Scan selected nodes one by one
        /// </summary>
        public static void Scan()
        {
            try
            {
                //scanning nodes, consists of uncovering nodes 
                //each node has 2 states-1 and 2
                //in first phase currently scanned node is highlighted
                //in second phase uncover occurs

                if (Phase1DoneForCurrentID)
                {
                    if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - ScannerElapsedTime >= WorldManager.WorldConfig.BombScannerTimeElapsing + WorldManager.WorldConfig.TimeOffsetToPhase2)
                    {
                        UncoverPhase2();
                    }


                }
                else
                {
                    if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - ScannerElapsedTime >= WorldManager.WorldConfig.BombScannerTimeElapsing)
                    {
                        UncoverPhase1();
                    }

                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// Start scanning for a bomb
        /// =uncover all previously selected nodes
        /// 
        /// </summary>
        public static bool StartScanning(Vector2 tapPos)
        {
            try
            {

                if (World.WorldManager.IsDefusingBomb)
                {
                    return false;
                }

                if (ScannerNodes == null || ScannerNodes.Count == 0)
                {
                    //no scanner nodes
                    //so player did not choose any nodes to scan
                    //cannot start scanning process
                    //show message informing that
                    //Util.MessageBox.ShowMessage("You have to select nodes to scan first!");

                    return false;
                }
                else
                {
                    //start the process if player holds on the HOLD button
                    if ((tapPos.X > ScanButtonRectangle.X && tapPos.X < ScanButtonRectangle.X+ScanButtonRectangle.Width) && (tapPos.Y > ScanButtonRectangle.Y && tapPos.Y < ScanButtonRectangle.Y+ScanButtonRectangle.Height))
                    {

                        ////see if any hidden (trackable) bombs are in this map cell
                        if (Levels.LevelManager.CurrentMap.CurrentMapCell.HasAnyTrackableBombs)
                        {
                            //if yes find bomb as well as letter
                            //find bomb
                            FindBomb();
                        }

                        //find letter in chosen nodes
                        FindLetter();

                       

                        //choosing nodes mode is done now
                        ChoosingNodes = false;
                        //set and reset rest of the flags:
                        IsScanning = true; //very important
                        ScannerElapsedTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                        CurrentScannedNodeID = 0;
                        Phase1DoneForCurrentID = false;
                        Phase2DoneForCurrentID = false;
                        EndScanning = false;
                        CurrentNodeHasBomb = false;

                        return true;
                    }
                }


                return false;

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }

        }

        /// <summary>
        /// End scanning
        /// </summary>
        public static void EndScanningProcess()
        {
            try
            {
                if (IsScanning && !ChoosingNodes)
                {

                    if (ScannerNodes != null)
                    {
                        //cache and file 
                        SaveProcessedNodes();

                    }

                    //SAVE energy value to file
                    //to be implemented...

                    //reset all fields and properties
                    //ChoosingNodes = false; //this is done by exitChoosingNodesMode()
                    ScannerNodes = null;
                    EnergyEstimate = Energy;
                    ScannerElapsedTime = 0;
                    CurrentScannedNodeID = -1;
                    Phase1DoneForCurrentID = false;
                    Phase2DoneForCurrentID = false;
                    EndScanning = false;
                    CurrentNodeHasBomb = false;
                    AtLeastOneNodeIsSelected = false;
                    ScanButtonPrepared = false;
                    ScanButtonRectangle = new Rectangle(-1, -1, -1, -1);

                    ///clear the bomb if uncover animation is not in progress and the bomb instance will nnot be cleared there
                    if (!UncoverBombAnimationInProgress)
                    {
                        BombToDrawInstance = null;
                    }

                    //THOSE ARE DONE IN DRAWBOMBUNCOVERED()
                    //UncoverBombAnimationTime = -1;
                    //UncoverBombAnimationFrame = -1;
                    ////UncoverBombAnimationInProgress = false;
                    ////BombToDrawInstance = null;

                    IsScanning = false;

                    //save world info (points, energy)
                    StorageManager.SaveWorldInfo();

                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Get ScannerNodes
        /// (nodes that surround avatar)
        /// </summary>
        public static void ChooseNodesToBeScanned()
        {
            //declare
            //List<Node> nodes;

            try
            {
                //if avatar is moving, then set ChoosingNodesPending and choose nodes after avatar stops
                if (Util.Cache.Avatar.IsMoving)
                {
                    if (AutoScannerON)
                    {
                        //keep showing scanning nodes as avatar is moving

                        //first create nodes
                        //nodes = PathFinding.InitNodesWithReturn();
                        ChoosingNodes = true; //start choosing nodes mode
                        GetNodesAroundAvatar(WorldManager.Nodes);
                        
                    }
                    else
                    {
                        //just show scanning mode when avaatar stops
                        ChoosingNodesModePending = true;
                    }
                }
                else
                {

                    //first create nodes
                    //nodes = PathFinding.InitNodesWithReturn();
                    ChoosingNodes = true; //start choosing nodes mode
                    GetNodesAroundAvatar(WorldManager.Nodes);
                   
                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// check if node exist on
        /// a list of already processed nodes
        /// </summary>
        /// <param name="scannerNode"></param>
        /// <returns></returns>
        public static bool DoesNodeExistOnProcessedList(Classes.ScannerNode scannerNode)
        {
            try
            {
                if (Util.Cache.ProcessedNodes != null)
                {
                    foreach (Classes.ScannerNode sn in Util.Cache.ProcessedNodes)
                    {
                        if (sn.Rectangle.X == scannerNode.Rectangle.X && sn.Rectangle.Y == scannerNode.Rectangle.Y && (sn.MapCellID==Levels.LevelManager.CurrentMap.CurrentMapCell.ID))
                        {
                            return true;
                        }
                    }
                }

                return false;

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }


        }

        /// <summary>
        /// Save processed nodes
        /// to file
        /// and to cache
        /// </summary>
        /// <returns></returns>
        public static void SaveProcessedNodes()
        {
            //declare
            List<Classes.ScannerNode> newNodesToSave = null;

            try
            {
                if (ScannerNodes != null)
                {
                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        if (sn.Selected && sn.DrawPhase2)
                        {
                            if (!DoesNodeExistOnProcessedList(sn))
                            {
                                //if cached list of processed nodes is empty, then create new instance
                                if (Util.Cache.ProcessedNodes == null)
                                {
                                    Util.Cache.ProcessedNodes = new List<Classes.ScannerNode>();
                                }

                                //set mapCell ID
                                sn.MapCellID = Levels.LevelManager.CurrentMap.CurrentMapCell.ID;

                                Util.Cache.ProcessedNodes.Add(sn);

                                //if new nodes to save list is empty, create new instance
                                //those nodes are the new ones, not saved to file yet
                                if (newNodesToSave == null)
                                {
                                    newNodesToSave = new List<Classes.ScannerNode>();
                                }

                            }
                        }
                    }

                    //SAVE nodeID and rowID to the file->scannedNodes
                    //so we know what was scanned already in the future
                    //save to file new nodes IMPLEMENT
                    //if (newNodesToSave != null)
                    //{
                    //    foreach (Classes.ScannerNode sn in newNodesToSave)
                    //    {
                    //        //save
                    //    }
                    //}

                }


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// user taps on a node that he wants to scan
        /// </summary>
        /// <param name="tapPos"></param>
        public static bool SelectNodeToScan(Vector2 tapPos)
        {
            //declare
            bool tappedOnAnyNode = false;

            try
            {
                //return true if tapped on a scanner node regardless if has energy or not
                //return false if tapped outside the scanner node

                if (ChoosingNodes && !(Util.Cache.Avatar.IsMoving && AutoScannerON))
                {

                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        //check if player tapped on a scanner node
                        if ((tapPos.X >= sn.Rectangle.X && tapPos.X <= (sn.Rectangle.X + sn.Rectangle.Width)) && (tapPos.Y >= sn.Rectangle.Y && tapPos.Y <= (sn.Rectangle.Y + sn.Rectangle.Height)))
                        {

                            //if this is already porocessed node, then skip
                            if (sn.Processed)
                            {
                                return true;
                            }



                            tappedOnAnyNode = true;

                            //if node is already selected, then unselect it
                            if (sn.Selected)
                            {
                                //give back energy:
                                EnergyEstimate += WorldManager.WorldConfig.UncoverEnergyCost;
                                sn.Selected = false;

                                IsAnyNodeSelected();

                                return true;
                            }
                            else
                            {
                                //not selected yet-select
                                if (EnergyEstimate >= WorldManager.WorldConfig.UncoverEnergyCost)
                                {
                                    //if player has enough energy then proceed:
                                    //Decrement energy estimate. Actual energy will be taken away when player will be scanning the nodes 
                                    //(in case no scanning is done and choosing nodes is canceled)
                                    EnergyEstimate -= WorldManager.WorldConfig.UncoverEnergyCost;
                                    sn.Selected = true;

                                    AtLeastOneNodeIsSelected = true;

                                    return true; //one node at 1 tap->selected,then return
                                }
                                else
                                {
                                    //player has not enough energy to do this, do not let select another node
                                    //show message box
                                    Util.MessageBox.ShowMessage("Not enough energy to proceed");
                                    //and return
                                    return true;
                                }


                            }


                        }
                        

                    }

                    //if player tapped outside scanner nodes, then exit scanning mode
                    if (!tappedOnAnyNode)
                    {
                        ExitChooseNodesMode();
                        return false;
                    }

                }
                else
                {
                    ExitChooseNodesMode();
                    return false;
                }


                //if we are here it means something went wrong and continue normal process in update method
                return false;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }

        }

        /// <summary>
        /// Is any node selected
        /// </summary>
        public static void IsAnyNodeSelected()
        {
            try
            {
                AtLeastOneNodeIsSelected = false;

                foreach (Classes.ScannerNode sn in ScannerNodes)
                {
                    if (sn.Selected)
                    {
                        AtLeastOneNodeIsSelected = true;
                        return;
                    }
                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// check if energy
        /// bar fits on the screen
        /// </summary>
        /// <param name="energyBarRect"></param>
        /// <returns></returns>
        public static bool IsEnergyBarOnTheScreen(Rectangle energyBarRect)
        {
            try
            {
                if (energyBarRect.X + energyBarRect.Width > Util.Cache.GraphicsDevice.Viewport.Width)
                {
                    //not on the screen
                    return false;
                }



                return true;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return true;
            }
        }

        /// <summary>
        /// Prepare scan button
        /// </summary>
        public static void PrepareScanButton()
        {
            //declare
            Rectangle avatarRect;
            Rectangle upLeftQuarter;
            Rectangle upRightQuarter;
            Rectangle downRightQuarter;
            Rectangle downLeftQuarter;

            try
            {
                if(!ScanButtonPrepared)
                {
                    avatarRect = new Rectangle((int)Util.Cache.Avatar.CurrentPosition.X, (int)Util.Cache.Avatar.CurrentPosition.Y, Util.Cache.Avatar.Width, Util.Cache.Avatar.Height);

                    upLeftQuarter = new Rectangle(0, 0, Util.Cache.GraphicsDevice.Viewport.Width / 2, Util.Cache.GraphicsDevice.Viewport.Height / 2);
                    upRightQuarter = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width / 2, 0, Util.Cache.GraphicsDevice.Viewport.Width / 2, Util.Cache.GraphicsDevice.Viewport.Height / 2);
                    downRightQuarter = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width / 2, Util.Cache.GraphicsDevice.Viewport.Height / 2, Util.Cache.GraphicsDevice.Viewport.Width / 2, Util.Cache.GraphicsDevice.Viewport.Height / 2);
                    downLeftQuarter = new Rectangle(0, Util.Cache.GraphicsDevice.Viewport.Height / 2, Util.Cache.GraphicsDevice.Viewport.Width / 2, Util.Cache.GraphicsDevice.Viewport.Height / 2);


                    #region upLeftQuarter

                    //if avatar is in up right quarter, draw scan button in down right quarter
                    if (avatarRect.X >= upLeftQuarter.Left && avatarRect.X <= upLeftQuarter.Right && avatarRect.Y >= upLeftQuarter.Top && avatarRect.Y<= upLeftQuarter.Bottom)
                    {
                        ScanButtonRectangle = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width - (Util.Cache.Avatar.Width * 3), Util.Cache.GraphicsDevice.Viewport.Height - (Util.Cache.Avatar.Height*2), Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonPrepared = true;
                        RedPointerRectangle = new Rectangle(ScanButtonRectangle.Left - (Util.Cache.Avatar.Width * 2), ScanButtonRectangle.Y + (ScanButtonRectangle.Height / 2), Util.Cache.Avatar.Width * 2, Util.Cache.Avatar.Width);
                        RedPointerDirection = 1;
                        return;
                    }


                    #endregion

                    #region upRightQuarter

                    //if avatar is in up right quarter, draw scan button in down left quarter
                    if (avatarRect.X >= upRightQuarter.Left && avatarRect.X <= upRightQuarter.Right && avatarRect.Y >= upRightQuarter.Top && avatarRect.Y <= upRightQuarter.Bottom)
                    {
                        //ScanButtonRectangle = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width - (Util.Cache.Avatar.Width * 3 + (Util.Cache.Avatar.Width / 2)),0-(Util.Cache.Avatar.Width / 2), Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonRectangle = new Rectangle(downLeftQuarter.X, Util.Cache.GraphicsDevice.Viewport.Height-(Util.Cache.Avatar.Height * 2), Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonPrepared = true;
                        RedPointerRectangle = new Rectangle(downLeftQuarter.X + (Util.Cache.Avatar.Width * 2), ScanButtonRectangle.Y + (ScanButtonRectangle.Height / 2), Util.Cache.Avatar.Width * 2, Util.Cache.Avatar.Width);
                        RedPointerDirection = 0;
                        return;
                    }

                    #endregion

                    #region downRightQuarter

                    //if avatar is in down right quarter, draw scan button in up left quarter
                    if (avatarRect.X >= downRightQuarter.Left && avatarRect.X <= downRightQuarter.Right && avatarRect.Y >= downRightQuarter.Top && avatarRect.Y <= downRightQuarter.Bottom)
                    {
                        //ScanButtonRectangle = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width - (Util.Cache.Avatar.Width * 3 + (Util.Cache.Avatar.Width / 2)), Util.Cache.GraphicsDevice.Viewport.Height-(Util.Cache.Avatar.Height * 2+(Util.Cache.Avatar.Width / 2)), Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonRectangle = new Rectangle(upLeftQuarter.X, upRightQuarter.Y, Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonPrepared = true;
                        RedPointerRectangle = new Rectangle(upLeftQuarter.X + (Util.Cache.Avatar.Width * 2), ScanButtonRectangle.Y + (ScanButtonRectangle.Height / 2), Util.Cache.Avatar.Width * 2, Util.Cache.Avatar.Width);
                        RedPointerDirection = 0;
                        return;
                    }


                    #endregion

                    #region downLeftQuarter

                    //if avatar is in up right quarter, draw scan button in up right quarter
                    if (avatarRect.X >= downLeftQuarter.Left && avatarRect.X <= downLeftQuarter.Right && avatarRect.Y >= downLeftQuarter.Top && avatarRect.Y <= downLeftQuarter.Bottom)
                    {
                        ScanButtonRectangle = new Rectangle(Util.Cache.GraphicsDevice.Viewport.Width - (Util.Cache.Avatar.Width * 3),(int)upRightQuarter.Y, Util.Cache.Avatar.Width * 3, Util.Cache.Avatar.Height * 2);
                        ScanButtonPrepared = true;
                        RedPointerRectangle = new Rectangle(ScanButtonRectangle.Left - (Util.Cache.Avatar.Width * 2), ScanButtonRectangle.Y + (ScanButtonRectangle.Height / 2), Util.Cache.Avatar.Width * 2, Util.Cache.Avatar.Width);
                        RedPointerDirection = 1;
                        return;
                    }

                    #endregion


                    //reset red pointer properties
                    RedPointerTimeOff = 0;
                    RedPointerTimeOn = 0;
                    RedPointerPointingScanButtonShown = false;
                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// Exit choose nodes mode
        /// </summary>
        public static void ExitChooseNodesMode()
        {
            try
            {
                IsScanning = true;//hack,must be true,so in EndScanningProcess everything is cleared (there is (if is scanning) IF)
                ChoosingNodes = false;
                EnergyEstimate = Energy;
                ChoosingNodesModePending = false;

                EndScanningProcess();
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// select nodes that surround avatar
        /// from a list of nodes
        /// </summary>
        /// <param name="nodes"></param>
        public static void GetNodesAroundAvatar(List<Node> nodes)
        {
            int[] avatarNode = null;
            Classes.ScannerNode scannerNode = null;
            float[] closestBombNode = null;
            float[] closestLetterNode = null;


            try
            {
                if (nodes != null)
                {
                    //get avatarNode (based on avatar position)
                    avatarNode = PathFinding.GetAvatarNode(true);

                    //check if this current map cell has any trackable bombs
                    if (Levels.LevelManager.CurrentMap.CurrentMapCell.HasAnyTrackableBombs)
                    {
                        //get position of closest bomb to avatar
                        closestBombNode = GetClosestBomb();
                    }

                    //get closest letter node
                    closestLetterNode = GetClosestLetterNode();


                    

                    if (avatarNode != null)
                    {
                        if (ScannerNodes == null)
                        {
                            ScannerNodes = new List<Classes.ScannerNode>();
                        }

                        ///loop thru nodes around avatar
                        for (int i = 0; i < World.WorldManager.Nodes.Count;i++)
                        {
                            //check if nodes are adjacent
                            if (PathFinding.AreNodesAdjacent(new int[] { avatarNode[0], avatarNode[1] }, new int[] { World.WorldManager.Nodes[i].ID, World.WorldManager.Nodes[i].Row }) & World.WorldManager.Nodes[i].IsWalkable)
                            {
                                //create new scanner node instance
                                scannerNode = new Classes.ScannerNode();
                                scannerNode.NodeID = World.WorldManager.Nodes[i].ID;
                                scannerNode.RowID = World.WorldManager.Nodes[i].Row;
                                scannerNode.Rectangle = World.WorldManager.Nodes[i].Rectangle;
                                scannerNode.HasLetter = World.WorldManager.Nodes[i].HasLetter;

                                //scannerNode.Warmth = World.WorldManager.Nodes[i].Warmth;

                                //check if avatar is already scanned/processed. IF yes set Processed=true so it could be disabled visually and logaically
                                if (DoesNodeExistOnProcessedList(scannerNode))
                                {
                                    scannerNode.Processed = true;
                                }
                                else
                                {
                                    scannerNode.Processed = false;

                                    //set node's warmth
                                    #region node warmth

                                    //if map cell has trackable bombs,then see what is closet ro the avatar, letter or bomb. if letter use 
                                    //letter to determine warmth and color of scanner, otheriwse use the bomb
                                    if (Levels.LevelManager.CurrentMap.CurrentMapCell.HasAnyTrackableBombs)
                                    {
                                        //if node has trackable bombs,then see if radar should show heat to the closest bomb or letter
                                        if (PathFinding.CalculateH(new float[] { scannerNode.Rectangle.X, scannerNode.Rectangle.Y }, closestLetterNode) < PathFinding.CalculateH(new float[] { scannerNode.Rectangle.X, scannerNode.Rectangle.Y }, closestBombNode))
                                        {
                                            //letter is closer
                                            if (closestLetterNode[0] == -1 && closestLetterNode[1] == -1)//if -1, then no closest letter on the map cell
                                            {
                                                scannerNode.Warmth = Util.Helpers.PublicEnums.NodeWarmth.VeryCold;
                                            }
                                            else
                                            {
                                                scannerNode.Warmth = DetermineNodeWarmth(PathFinding.CalculateH(new float[] { scannerNode.Rectangle.X, scannerNode.Rectangle.Y }, closestLetterNode));
                                            }
                                        }
                                        else
                                        {

                                            if (closestBombNode[0] == -1 && closestBombNode[1] == -1)//if -1, then no closest bomb on the map cell
                                            {
                                                scannerNode.Warmth = Util.Helpers.PublicEnums.NodeWarmth.VeryCold;
                                            }
                                            else
                                            {
                                                //bomb is closer
                                                scannerNode.Warmth = DetermineNodeWarmth(PathFinding.CalculateH(new float[] { scannerNode.Rectangle.X, scannerNode.Rectangle.Y }, closestBombNode));
                                            }
                                        }

                                    }
                                    else
                                    {
                                        if (closestLetterNode[0] == -1 && closestLetterNode[1] == -1)//if -1, then no closest letter on the map cell
                                        {
                                            scannerNode.Warmth = Util.Helpers.PublicEnums.NodeWarmth.VeryCold;
                                        }
                                        else
                                        {
                                            //first determine distance to the closest letter
                                            scannerNode.Warmth = DetermineNodeWarmth(PathFinding.CalculateH(new float[] { scannerNode.Rectangle.X, scannerNode.Rectangle.Y }, closestLetterNode));
                                        }
                                    }

                                    #endregion





                                    //add to the ilst of scanner nodes
                                    ScannerNodes.Add(scannerNode);
                                }

                            }


                        }



                        avatarNode = null;

                    }


                }



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }



        }

        /// <summary>
        /// Determine node warmth
        /// </summary>
        /// <param name="H"></param>
        /// <returns></returns>
        public static Util.Helpers.PublicEnums.NodeWarmth DetermineNodeWarmth(float H)
        {
            try
            {
                if (H <= WorldManager.WorldConfig.NodeVeryHotValue)
                {
                    //about 750
                    return Util.Helpers.PublicEnums.NodeWarmth.VeryHot;
                }


                if (H <= WorldManager.WorldConfig.NodeHotValue)
                {
                    //about 1050
                    return Util.Helpers.PublicEnums.NodeWarmth.Hot;
                }


                if (H <= WorldManager.WorldConfig.NodeWarmValue)
                {
                    //about 1350
                    return Util.Helpers.PublicEnums.NodeWarmth.Warm;
                }


                if (H <= WorldManager.WorldConfig.NodeColdValue)
                {
                    //about 1650
                    return Util.Helpers.PublicEnums.NodeWarmth.Cold;
                }

                //if H is more than cold value than it must be VERY COLD value
                if (H > WorldManager.WorldConfig.NodeColdValue)
                {
                    //about 1900-2600
                    return Util.Helpers.PublicEnums.NodeWarmth.VeryCold;
                }



                return Util.Helpers.PublicEnums.NodeWarmth.None;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return Util.Helpers.PublicEnums.NodeWarmth.None;
            }

        }

        /// <summary>
        /// Get closest bomb node
        /// *used to know to which bomb colors are going to be changed
        /// *RETURN position of closest bomb
        /// </summary>
        public static float[] GetClosestBomb()
        {
            //declare
            float H;
            List<float[]> AllHs = null;
            int chosenIndex = -1;

            try
            {
                if (Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs != null)
                {
                    for (int i = 0; i < Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs.Count; i++)
                    {
                        //if bomb already found or is not trackable, skip
                        if (Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Found || !Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Trackable)
                        {
                            //we only want un found bombs, so ignore already found
                            continue;
                        }

                        //calculate H, from avatar to bomb
                        H = PathFinding.CalculateH(new float[] { Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Position.X, Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Position.Y });

                        //add h to the list of allHs
                        if (AllHs == null)
                        {
                            //create allHs list if null
                            AllHs = new List<float[]>();

                        }

                        //add H, bomb pos to AllHS list
                        AllHs.Add(new float[] { H, Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Position.X, Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs[i].Position.Y });




                    } //for each bomb

                    if (AllHs != null)
                    {
                        //foreach allHS
                        for (int i1 = 0; i1 < AllHs.Count; i1++)
                        {
                            //see if there is a lower H
                            if (!IsThereLowerH(AllHs[i1][0], AllHs))
                            {
                                //if no lower H, then we got the bomb closest to the avatar
                                //all we need
                                chosenIndex = i1;
                                break;


                            } //else check another H form the list
                        
                        }


                    }


                }

                //if a chosen index has been specified,return chosen bomb's pos
                if (chosenIndex > -1)
                {
                    return new float[] { AllHs[chosenIndex][1], AllHs[chosenIndex][2] };
                }

                //return nothing -0,0 is basically nothing in this case
                return new float[] { -1, -1 };

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return new float[] { 0, 0 };  //return nothing -0,0 is basically nothing in this case
            }
        }

        /// <summary>
        /// get closest letter node
        /// -closest to avatar
        /// </summary>
        public static float[] GetClosestLetterNode()
        {
            //delcare
            float H = -1;
            List<float[]> allHs = null;
            int chosenIndex = -1;

            try
            {
                if (Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters != null)
                {
                    for (int i = 0; i < Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters.Count; i++)
                    {
                        if (Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].MapCellID==Levels.LevelManager.CurrentMap.CurrentMapCell.ID && Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Pos != null && !Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Uncovered)
                        {
                            //calculate H to this letter
                            H = PathFinding.CalculateH(new float[] { Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Pos[0], Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Pos[1] });

                            //add this H to the list that will be processed
                            if (allHs == null)
                            {
                                //create allHs list if null
                               allHs = new List<float[]>();

                            }
                            //add here:
                            allHs.Add((new float[] { H, Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Pos[0], Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters[i].Pos[1] }));

                            
                        }
                    }

                    //get lowest H from the collection of all HS
                    if (allHs != null)
                    {
                        //foreach allHS
                        for (int i1 = 0; i1 < allHs.Count; i1++)
                        {
                            //see if there is a lower H
                            if (!IsThereLowerH(allHs[i1][0], allHs))
                            {
                                //if no lower H, then we got the bomb closest to the avatar
                                //all we need
                                chosenIndex = i1;
                                break;


                            } //else check another H form the list
                        
                        }


                    }


                }

                //if a chosen index has been specified,return chosen letter's pos
                if (chosenIndex > -1)
                {
                    return new float[] { allHs[chosenIndex][1], allHs[chosenIndex][2] };
                }

                //return nothing -0,0 is basically nothing in this case
                return new float[] { -1, -1 };


                



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return new float[] { 0, 0 };
            }
        }

        /// <summary>
        /// Is there lower H
        /// </summary>
        /// <param name="number"></param>
        /// <param name="numbers"></param>
        /// <returns></returns>
        public static bool IsThereLowerH(float number, List<float[]> numbers)
        {
            try
            {
                for (int i = 0; i < numbers.Count; i++)
                {
                    //if one of the numbers is less than number, then return true
                    if (numbers[i][0] < number)
                    {
                        return true; //we need the lowest, so break the loop and check another item
                    }
                    

                }

                return false;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }
        }

        /// <summary>
        /// Find a bomb in scanner nodes
        /// I have to know from beginning where the bomb is
        /// </summary>
        public static void FindBomb()
        {
            //declare
            List<Classes.ScannerNode> helpList = new List<Classes.ScannerNode>();

            try
            {
                //first, remove all ndoes that are not selected for scanning-do so by filtering,
                //add all selected nodes to helplist, then clear scannerNodes list,and add selected nodes from help list to the scannernodes list
                for (int i = 0; i < ScannerNodes.Count; i++)
                {
                    if (ScannerNodes[i].Selected)
                    {
                        //if the node is not selected to scan, then remove it from the list
                        helpList.Add(ScannerNodes[i]);
                    }
                }

                //now from help list to scanner nodes , new scanner ndoes list but without not selected ndoes
                ScannerNodes = null;
                ScannerNodes = new List<Classes.ScannerNode>();
                for(int i1=0;i1<helpList.Count;i1++)
                {
                    //assign scanner id to the selected node
                    helpList[i1].ScannerID = i1;
                    //add selected node to the list
                    ScannerNodes.Add(helpList[i1]);
                }
                //clear the helplist
                helpList = null;


                //now, check if any of scannerNodes has bomb
                foreach (Classes.ScannerNode sn in ScannerNodes)
                {
                    foreach (Util.Classes.BombToDraw btd in Levels.LevelManager.CurrentMap.CurrentMapCell.Bombs)
                    {
                        if (sn.Rectangle.X == btd.Position.X && sn.Rectangle.Y == btd.Position.Y && btd.Trackable)
                        {
                            sn.NodeType = Util.Helpers.PublicEnums.NodeType.Bomb;
                            sn.BombToDrawInstance = btd;
                            return; //we have what we wanted-the bomb then return (only 1 bomb can be found in 1 scanning)
                        }
                    }


                }


               



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// find out which node has letter
        /// if any
        /// </summary>
        public static void FindLetter()
        {
            //declare
            List<Classes.ScannerNode> helpList = new List<Classes.ScannerNode>();

            try
            {
                //first, remove all ndoes that are not selected for scanning-do so by filtering,
                //add all selected nodes to helplist, then clear scannerNodes list,and add selected nodes from help list to the scannernodes list
                for (int i = 0; i < ScannerNodes.Count; i++)
                {
                    if (ScannerNodes[i].Selected)
                    {
                        //if the node is not selected to scan, then remove it from the list
                        helpList.Add(ScannerNodes[i]);
                    }
                }

                //now from help list to scanner nodes , new scanner ndoes list but without not selected ndoes
                ScannerNodes = null;
                ScannerNodes = new List<Classes.ScannerNode>();

                for (int i1 = 0; i1 < helpList.Count; i1++)
                {
                    //assign scanner id to the selected node
                    helpList[i1].ScannerID = i1;
                    //add selected node to the list
                    ScannerNodes.Add(helpList[i1]);
                }

                //clear the helplist
                helpList = null;


                //now, check if any of scannerNodes has letter
                foreach (Classes.ScannerNode sn in ScannerNodes)
                {
                    foreach (Classes.Letter letter in Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters)
                    {
                        if (letter.MapCellID == Levels.LevelManager.CurrentMap.CurrentMapCell.ID)
                        {
                            //if letter is not uncovered yet
                            if (letter.Pos != null && !letter.Uncovered)
                            {
                                //if 
                                if (sn.Rectangle.X == letter.Pos[0] && sn.Rectangle.Y == letter.Pos[1])
                                {
                                    sn.NodeType = Util.Helpers.PublicEnums.NodeType.Letter;
                                    sn.LetterInstnace = letter;
                                    return; //we have what we wanted-the letter then return (only 1 letter can be found in 1 scanning)
                                }
                            }
                        }
                    }


                }






            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// Uncover phase 1 of a node
        /// </summary>
        public static void UncoverPhase1()
        {
            try
            {
                foreach (Classes.ScannerNode sn in ScannerNodes)
                {
                    if (sn.ScannerID == CurrentScannedNodeID)
                    {
                        sn.DrawPhase1 = true;
                        Phase1DoneForCurrentID = true;
                        return;
                    }
                }



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// Uncover phase 2 of a node
        /// </summary>
        public static void UncoverPhase2()
        {
            try
            {
                foreach (Classes.ScannerNode sn in ScannerNodes)
                {
                    if (sn.ScannerID == CurrentScannedNodeID)
                    {
                        sn.DrawPhase2 = true;
                        sn.DrawPhase1 = false;
                        Phase1DoneForCurrentID = false;
                        TakeAwayEnergy(); //node has been scanned and uncovered,so take away energy for it

                        if (sn.NodeType == Util.Helpers.PublicEnums.NodeType.Bomb)
                        {
                            CurrentNodeHasBomb = true; //If a bomb has been found, Then set flag to true and end. DrawUncoverbombAnimation will end the process of scanning.
                            BombToDrawInstance = sn.BombToDrawInstance;
                            sn.BombToDrawInstance = null;

                            //that's it, no need to increment current scanned id
                            //because scanning will be ended in drawUncoverBomb()
                            //ONLY 1 BOMB CAN BE FOUND IN 1 SCANNING

                           
                        }
                        else if (sn.NodeType == Util.Helpers.PublicEnums.NodeType.Letter)
                        {
                            CurrentNodeHasLetter = true;
                            LetterInstance = sn.LetterInstnace;
                            sn.LetterInstnace = null;


                        }
                        else
                        {
                            //if this was the last node, then stop scanning
                            if (sn.ScannerID == ScannerNodes.Count - 1)
                            {
                                EndScanning = true;
                            }
                            else
                            {
                                //if there are more nodes to check
                                //then increment current scanned id by 1 to check next node
                                CurrentScannedNodeID += 1;

                            }

                        }

                        //we only care about current node
                        return;
                    }
                }



            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// add energy and svae
        /// </summary>
        /// <param name="value"></param>
        public static void AddEnergy(int value)
        {
            try
            {
                if (Energy + value > 100)
                {
                    Energy = 100;
                }
                else
                {
                    Energy += value;
                }

                EnergyEstimate = Energy;

                //save
                StorageManager.SaveWorldInfo();


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// add battery level
        /// </summary>
        /// <param name="value"></param>
        public static void AddBattery(int value)
        {
            try
            {
                BatteryLevel += value;

                if (BatteryLevel > 100)
                {
                    BatteryLevel = 100;
                }

                //reset battery counter
                Util.Cache.Avatar.CheckpointsReached = 0;
                

                //save
                StorageManager.SaveWorldInfo();

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// refill auto scanner battery
        /// </summary>
        public static void RefillBattery()
        {
            try
            {
                if (!Util.Cache.Avatar.IsMoving && BatteryLevel < 100)
                {
                    //if time to refill has passed,refill
                    if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - BatteryLevelRefillTime > World.WorldManager.WorldConfig.AutoScannerBatteryRefillTime)
                    {
                        BatteryLevel += WorldManager.WorldConfig.RefillValue;

                        if (BatteryLevel > 100)
                        {
                            BatteryLevel = 100;
                        }

                        //reset timer
                       BatteryLevelRefillTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                        
                        //save
                       StorageManager.SaveWorldInfo();
                    }

                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// add energy and svae
        /// </summary>
        /// <param name="value"></param>
        public static void AddMarker(Util.Helpers.PublicEnums.MarkerType marker,int value)
        {
            try
            {

                switch (marker)
                {
                    case Util.Helpers.PublicEnums.MarkerType.Green:
                        {
                            WorldManager.GreenMarkerCount += value;
                            break;
                        }
                    case Util.Helpers.PublicEnums.MarkerType.Orange:
                        {
                            WorldManager.OrangeMarkerCount += value;
                            break;
                        }
                    case Util.Helpers.PublicEnums.MarkerType.Red:
                        {
                            WorldManager.RedMarkerCount += value;
                            break;
                        }
                }


             

                //save
                StorageManager.SaveWorldInfo();


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// add energy and svae
        /// </summary>
        /// <param name="value"></param>
        public static void TakeAwayMarker(Util.Helpers.PublicEnums.MarkerType marker, int value)
        {
            try
            {

                switch (marker)
                {
                    case Util.Helpers.PublicEnums.MarkerType.Green:
                        {
                            WorldManager.GreenMarkerCount -= value;
                            break;
                        }
                    case Util.Helpers.PublicEnums.MarkerType.Orange:
                        {
                            WorldManager.OrangeMarkerCount -= value;
                            break;
                        }
                    case Util.Helpers.PublicEnums.MarkerType.Red:
                        {
                            WorldManager.RedMarkerCount -= value;
                            break;
                        }
                }


                //save
                StorageManager.SaveWorldInfo();


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Scanning takes energy
        /// subtract x energy for each scanned node
        /// </summary>
        public static void TakeAwayEnergy()
        {
            try
            {
                Energy -= WorldManager.WorldConfig.UncoverEnergyCost;

                if (Energy < 0)
                {
                    Energy = 0;
                }

                EnergyEstimate = Energy; //level up energy estimate

               

                //save
                StorageManager.SaveWorldInfo();
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }

        }

        /// <summary>
        /// take away auto scanner battery
        /// if avatar reached necessary number of move points
        /// </summary>
        /// <param name="ct"></param>
        public static bool TakeAwayAutoScannerBattery(int ct)
        {
            try
            {
                if (ct >= WorldManager.WorldConfig.BatteryUsageStep)
                {
                    BatteryLevel -= WorldManager.WorldConfig.TakeAwayValue;

                    if (BatteryLevel < 0)
                    {
                        BatteryLevel = 0;
                    }

                    //save
                    StorageManager.SaveWorldInfo();

                    return true; //return true so ct could be reseted
                }

                return false;
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return false;
            }
        }

        #region DRAWING

        /// <summary>
        /// Draw choosing nodes mode
        /// -energy estimate bar
        /// -nodes adjacent to the avatar
        /// -selection (if made by player) (selected node)
        /// </summary>
        public static void DrawChoosingNodesMode()
        {
            try
            {
                if (ChoosingNodes && ScannerNodes!=null)
                {
                    if (!Util.Cache.Avatar.IsMoving)
                    {
                        //draw energy bar estimate
                        DrawEnergyBarEstimate();
                    }


                    #region GET TEXTURES

                    if (!_NodesTexturesSet)
                    {
                        _VeryHotTexture = Util.Cache.GetTexture("ScannerNodeVeryHot").Text2D;
                        _HotTexture = Util.Cache.GetTexture("ScannerNodeHot").Text2D;
                        _WarmTexture = Util.Cache.GetTexture("ScannerNodeWarm").Text2D;
                        _ColdTexture = Util.Cache.GetTexture("ScannerNodeCold").Text2D;
                        _VeryColdTexture = Util.Cache.GetTexture("ScannerNodeVeryCold").Text2D;

                        _NodesTexturesSet = true;
                    }

                    #endregion

                    //draw nodes that user can select or already selected
                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        if (sn.Processed)
                        {
                            //node already processed, draw disabled
                            Util.Cache.Draw(Util.Cache.GetTexture("DisabledNode").Text2D, sn.Rectangle, Color.White);

                        }
                        else
                        {
                            //node not processed yet, draw enabled

                            if (sn.Selected)
                            {
                                Util.Cache.Draw(Util.Cache.GetTexture("SelectedScannerNode").Text2D, sn.Rectangle, Color.White);


                            }
                            else
                            {
                                #region DRAW color depending from node's warmth

                                switch (sn.Warmth)
                                {
                                    case Util.Helpers.PublicEnums.NodeWarmth.VeryCold:
                                        {
                                            Util.Cache.Draw(_VeryColdTexture, sn.Rectangle, Color.White);
                                            break;
                                        }
                                    case Util.Helpers.PublicEnums.NodeWarmth.Cold:
                                        {
                                            Util.Cache.Draw(_ColdTexture, sn.Rectangle, Color.White);
                                            break;
                                        }
                                    case Util.Helpers.PublicEnums.NodeWarmth.Warm:
                                        {
                                            Util.Cache.Draw(_WarmTexture, sn.Rectangle, Color.White);
                                            break;
                                        }
                                    case Util.Helpers.PublicEnums.NodeWarmth.Hot:
                                        {
                                            Util.Cache.Draw(_HotTexture, sn.Rectangle, Color.White);
                                            break;
                                        }
                                    case Util.Helpers.PublicEnums.NodeWarmth.VeryHot:
                                        {
                                            Util.Cache.Draw(_VeryHotTexture, sn.Rectangle, Color.White);
                                            break;
                                        }
                                }

                                #endregion

                       
                            }
                        }

                    }




                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// Draw scanning
        /// </summary>
        public static void DrawScanning()
        {
            try
            {
                if (IsScanning)
                {

                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        if (sn.Selected)
                        {
                            if (sn.DrawPhase1)
                            {
                                //draw node's phase 1
                                Util.Cache.Draw(Util.Cache.GetTexture("ScannerNodePhase1").Text2D, sn.Rectangle, Color.White);
                            }

                            if (sn.DrawPhase2)
                            {
                                //draw node's phase 2
                                Util.Cache.Draw(Util.Cache.GetTexture("ScannerNodePhase2").Text2D, sn.Rectangle, Color.White);

                            }


                            if ((!sn.DrawPhase1 && !sn.DrawPhase2))
                            {
                                //draw node selected but not in phase 1 and phase 2
                                Util.Cache.Draw(Util.Cache.GetTexture("SelectedScannerNode").Text2D, sn.Rectangle, Color.White);

                            }
                        }
                    }


                    //draw energy bar
                    DrawEnergyBar();


                    //if end of scanning
                    if (EndScanning)
                    {
                        EndScanningProcess();
                        //show scanning failure message, as no bomb has been found (all nodes scanned, no bomb)
                        Util.MessageBox.ShowMessage("Scanning failed. Nothing has been found");

                    }
                }


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Draw Scan Button
        /// </summary>
        public static void DrawScanButton()
        {
            try
            {
                if (IsScanning || ChoosingNodes && AtLeastOneNodeIsSelected)
                {
                    if (ScanButtonPrepared)
                    {
                        Util.Cache.Draw(Util.Cache.GetTexture("ScanButton").Text2D, ScanButtonRectangle, Color.White);

                        #region Draw Red pointer (only if scanning)

                        if (!IsScanning) //if started scanning, no need to show the pointer anymore
                        {
                            //red pointer must  be flashing, co draw it for x seconds, then stop drawing, then draw agian.
                            if (RedPointerPointingScanButtonShown)
                            {
                                
                                    if (RedPointerDirection == 0)
                                    {
                                        //left
                                        Util.Cache.Draw(Util.Cache.GetTexture("RedPointerLeft").Text2D, RedPointerRectangle, Color.White);
                                    }
                                    else
                                    {
                                        //right
                                        Util.Cache.Draw(Util.Cache.GetTexture("RedPointerRight").Text2D, RedPointerRectangle, Color.White);
                                    }

                                //reset after the red pointer was drawn for x seconds
                                    if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - RedPointerTimeOn > World.WorldManager.WorldConfig.RedPointerFlashTimeON)
                                    {
                                        //reset redPointerTimeon
                                        RedPointerTimeOn = 0;
                                        RedPointerPointingScanButtonShown = false; //disable red pointer now
                                        RedPointerTimeOff = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                                    }
                            }
                            else
                            {
                                //start drawing pointer again after x seconds.
                                if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - RedPointerTimeOff > World.WorldManager.WorldConfig.RedPointerFlashTimeOFF)
                                {
                                    RedPointerPointingScanButtonShown = true;
                                    RedPointerTimeOn = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                                }
                              

                            }
                        }

                        #endregion
                    }
                    else
                    {
                        PrepareScanButton();
                    }
                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Draw bomb uncovering animation
        /// and complete the scanning process
        /// </summary>
        public static void DrawBombUncovered()
        {
            try
            {
                if (CurrentNodeHasBomb)
                {
                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        if (sn.ScannerID == CurrentScannedNodeID && sn.NodeType == Util.Helpers.PublicEnums.NodeType.Bomb)
                        {
                            //show the bomb
                            BombToDrawInstance.IsHidden = false;
                            //animation in progress=true
                            UncoverBombAnimationInProgress = true;
                            CurrentNodeHasBomb = false; //setting of the animation occurs only once,then animation begins

                            UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                            UncoverBombAnimationFrame = 0;
                            EndScanningProcess(); //Finish scanning. 1 bomb can be found at 1 scanning. Just show bomb uncovered animation.

                            //show information that scanning has eneded successfuly
                            //Util.MessageBox.ShowMessage("Scanning completed successfuly");

                            return; //nothing else to do here

                        }


                    }

                }
                else
                {
                    //current node has not the bomb
                    //is the uncover bomb animation in progress?
                    if (UncoverBombAnimationInProgress)
                    {
                        //has enough time passed to show another frame?
                        if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - UncoverBombAnimationTime >= WorldManager.WorldConfig.BombUncoverAnimationTime)
                        {
                            switch (UncoverBombAnimationFrame)
                            {
                                case 0:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame1").Text2D, new Rectangle((int)BombToDrawInstance.Position.X, (int)BombToDrawInstance.Position.Y, WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);

                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                       
                                        WorldManager.AwardMessage("Energy Gained", 100, "+", string.Empty, new int[] { 33, 70, 255, 255 }, 0.001f);

                                        //give 10 energy to the player
                                        AddEnergy(100);

                                        break;
                                    }
                                case 1:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame2").Text2D, new Rectangle((int)BombToDrawInstance.Position.X - (WorldManager.WorldConfig.NodeWidth / 2), (int)BombToDrawInstance.Position.Y, WorldManager.WorldConfig.NodeWidth + WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        

                                        break;
                                    }
                                case 2:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame3").Text2D, new Rectangle((int)BombToDrawInstance.Position.X-(WorldManager.WorldConfig.NodeWidth), (int)BombToDrawInstance.Position.Y, WorldManager.WorldConfig.NodeWidth*3, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        break;
                                    }
                                case 3:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame4").Text2D, new Rectangle((int)BombToDrawInstance.Position.X - ((WorldManager.WorldConfig.NodeWidth) + (WorldManager.WorldConfig.NodeWidth/2)), (int)BombToDrawInstance.Position.Y-(WorldManager.WorldConfig.NodeHeight/2), WorldManager.WorldConfig.NodeWidth*4, WorldManager.WorldConfig.NodeHeight*2), Color.White);
                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //WorldManager.AwardMessage("Markers Gained", 10, "+", "Green +10 Orange +10 Red", new int[] { 33, 70, 255, 150 }, 0.001f);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Green, 10);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Orange, 10);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Red, 10);

                                        break;
                                    }
                                case 4:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame5").Text2D, new Rectangle((int)BombToDrawInstance.Position.X - (WorldManager.WorldConfig.NodeWidth*2), (int)BombToDrawInstance.Position.Y-(WorldManager.WorldConfig.NodeHeight), WorldManager.WorldConfig.NodeWidth*5, WorldManager.WorldConfig.NodeHeight*3), Color.White);
                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        break;
                                    }
                                case 5:
                                    {
                                        //white node (imitating a flash)
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame6").Text2D, new Rectangle((int)BombToDrawInstance.Position.X, (int)BombToDrawInstance.Position.Y, WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverBombAnimationFrame += 1;
                                        UncoverBombAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                       

                                        break;
                                    }
                                case 6:
                                    {
                                        //do not draw anything, just complete the animation
                                        UncoverBombAnimationTime = -1;
                                        UncoverBombAnimationFrame = -1;
                                        UncoverBombAnimationInProgress = false;

                                        //save that the bomb has been found
                                        //WorldManager.SaveBombAfterEffect(BombToDrawInstance, 1);

                                        //set bopmbt to draw instance to null
                                        BombToDrawInstance = null;
                                        

                                        //save bomb found
                                        Levels.LevelManager.CurrentMap.BombFound = true;
                                      //save bomb state for the map
                                        StorageManager.SaveBombStateForTheMap();

                                        WorldManager.AwardPoints(Util.Helpers.PublicEnums.AcheivementType.BombFound, 1000,0.001f);

                                        

                                        break;
                                    }



                            }


                        }

                    }


                }


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// Draw letter uncovering animation
        /// and complete the scanning process
        /// </summary>
        public static void DrawLetterUncovered()
        {
            try
            {
                if (CurrentNodeHasLetter)
                {
                    foreach (Classes.ScannerNode sn in ScannerNodes)
                    {
                        if (sn.ScannerID == CurrentScannedNodeID && sn.NodeType == Util.Helpers.PublicEnums.NodeType.Letter)
                        {
                            //draw letter
                            LetterInstance.Draw();
                            //animation in progress=true
                            UncoverLetterAnimationInProgress = true;
                            CurrentNodeHasLetter = false; //setting of the animation occurs only once,then animation begins

                            UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;
                            UncoverLetterAnimationFrame = 0;
                            EndScanningProcess(); //Finish scanning. 1 bomb can be found at 1 scanning. Just show bomb uncovered animation.

                            //show information that scanning has eneded successfuly
                            //Util.MessageBox.ShowMessage("Scanning completed successfuly");

                            

                            return; //nothing else to do here

                        }


                    }

                }
                else
                {
                    //current node has not the letter
                    //is the uncover letter animation in progress?
                    if (UncoverLetterAnimationInProgress)
                    {
                        //has enough time passed to show another frame?
                        if (Util.Cache.GameTime.TotalGameTime.TotalMilliseconds - UncoverLetterAnimationTime >= WorldManager.WorldConfig.LetterUncoverAnimationTime)
                        {
                            switch (UncoverLetterAnimationFrame)
                            {
                                case 0:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame1").Text2D, new Rectangle(LetterInstance.Pos[0], LetterInstance.Pos[1], WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);

                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        WorldManager.AwardMessage("Energy Gained", 100, "+", string.Empty, new int[] { 33, 70, 255, 255 }, 0.001f);

                                        //give 10 energy to the player
                                        AddEnergy(100);

                                        break;
                                    }
                                case 1:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame2").Text2D, new Rectangle(LetterInstance.Pos[0] - (WorldManager.WorldConfig.NodeWidth / 2), LetterInstance.Pos[1], WorldManager.WorldConfig.NodeWidth + WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        break;
                                    }
                                case 2:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame3").Text2D, new Rectangle(LetterInstance.Pos[0] - (WorldManager.WorldConfig.NodeWidth), LetterInstance.Pos[1], WorldManager.WorldConfig.NodeWidth * 3, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        break;
                                    }
                                case 3:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame4").Text2D, new Rectangle(LetterInstance.Pos[0] - ((WorldManager.WorldConfig.NodeWidth) + (WorldManager.WorldConfig.NodeWidth / 2)), LetterInstance.Pos[1] - (WorldManager.WorldConfig.NodeHeight / 2), WorldManager.WorldConfig.NodeWidth * 4, WorldManager.WorldConfig.NodeHeight * 2), Color.White);
                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        //WorldManager.AwardMessage("Markers Gained", 10, "+", "Green +10 Orange +10 Red", new int[] { 33, 70, 255, 150 }, 0.001f);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Green, 10);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Orange, 10);
                                        //AddMarker(Util.Helpers.PublicEnums.MarkerType.Red, 10);

                                        break;
                                    }
                                case 4:
                                    {
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame5").Text2D, new Rectangle((int)LetterInstance.Pos[0] - (WorldManager.WorldConfig.NodeWidth * 2), (int)LetterInstance.Pos[1] - (WorldManager.WorldConfig.NodeHeight), WorldManager.WorldConfig.NodeWidth * 5, WorldManager.WorldConfig.NodeHeight * 3), Color.White);
                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        break;
                                    }
                                case 5:
                                    {
                                        //white node (imitating a flash)
                                        Util.Cache.Draw(Util.Cache.GetTexture("UncoverBombAnimationFrame6").Text2D, new Rectangle((int)LetterInstance.Pos[0], (int)LetterInstance.Pos[1], WorldManager.WorldConfig.NodeWidth, WorldManager.WorldConfig.NodeHeight), Color.White);
                                        UncoverLetterAnimationFrame += 1;
                                        UncoverLetterAnimationTime = Util.Cache.GameTime.TotalGameTime.TotalMilliseconds;

                                        //draw letter
                                        LetterInstance.Draw();

                                        break;
                                    }
                                case 6:
                                    {
                                        //do not draw anything, just complete the animation
                                       UncoverLetterAnimationTime = -1;
                                        UncoverLetterAnimationFrame = -1;
                                        UncoverLetterAnimationInProgress = false;
                                       //increment number of letters found
                                        Levels.LevelManager.CurrentMap.LettersFound += 1;

                                        LetterInstance.Uncovered = true;

                                        //see if the whole word has been discored with discovering that letter
                                        if (Levels.LevelManager.CurrentMap.LettersFound == Levels.LevelManager.CurrentMap.ChosenSecretWord.Letters.Count)
                                        {
                                            Levels.LevelManager.CurrentMap.ChosenSecretWord.Solved = true;
                                            WorldManager.AwardPoints(Util.Helpers.PublicEnums.AcheivementType.AllLettersFound, Levels.LevelManager.CurrentMap.PointsForFindingAllLetters, 0.001f);

                                        }
                                        else
                                        {
                                            WorldManager.AwardPoints(Util.Helpers.PublicEnums.AcheivementType.LetterFound, Levels.LevelManager.CurrentMap.PointsForFiding1Letter, 0.001f);
                                        }

                                        //save that letter has been found
                                        StorageManager.SaveWordStateForTheMap();


                                        //set letter instance to null
                                        LetterInstance = null;


                                        break;
                                    }



                            }


                        }

                    }


                }


            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// draw energy bar estimate
        /// </summary>
        public static void DrawEnergyBarEstimate()
        {
            //declare
            string texture = "0P";
            Rectangle energyBarRect = new Rectangle((int)Util.Cache.Avatar.CurrentPosition.X + (Util.Cache.Avatar.Width * 2) + 5, (int)Util.Cache.Avatar.CurrentPosition.Y, WorldManager.WorldConfig.EnergyBarWidth, WorldManager.WorldConfig.EnergyBarHeight);

            try
            {

                #region get texture based on energy estimate value

                switch (EnergyEstimate)
                {
                    case 0:
                        {
                            texture = "0P";

                            break;
                        }
                    case 5:
                        {
                            texture = "5P";

                            break;
                        }
                    case 10:
                        {
                            texture = "10P";

                            break;
                        }
                    case 15:
                        {
                            texture = "15P";

                            break;
                        }
                    case 20:
                        {
                            texture = "20P";

                            break;
                        }
                    case 25:
                        {
                            texture = "25P";

                            break;
                        }
                    case 30:
                        {
                            texture = "30P";

                            break;
                        }
                    case 35:
                        {
                            texture = "35P";

                            break;
                        }
                    case 40:
                        {
                            texture = "40P";

                            break;
                        }
                    case 45:
                        {
                            texture = "45P";

                            break;
                        }
                    case 50:
                        {
                            texture = "50P";

                            break;
                        }
                    case 55:
                        {
                            texture = "55P";

                            break;
                        }
                    case 60:
                        {
                            texture = "60P";

                            break;
                        }
                    case 65:
                        {
                            texture = "65P";

                            break;
                        }
                    case 70:
                        {
                            texture = "70P";

                            break;
                        }
                    case 75:
                        {
                            texture = "75P";

                            break;
                        }
                    case 80:
                        {
                            texture = "80P";

                            break;
                        }
                    case 85:
                        {
                            texture = "85P";

                            break;
                        }
                    case 90:
                        {
                            texture = "90P";

                            break;
                        }
                    case 95:
                        {
                            texture = "95P";

                            break;
                        }
                    case 100:
                        {
                            texture = "100P";

                            break;
                        }


                }
                #endregion

                if (IsEnergyBarOnTheScreen(energyBarRect))
                {
                    Util.Cache.Draw(Util.Cache.GetTexture(texture).Text2D, energyBarRect, Color.White);
                }
                else
                {
                    //draw on the left
                    energyBarRect.X = (int)Util.Cache.Avatar.CurrentPosition.X - (Util.Cache.Avatar.Width * 4) - 5;

                    Util.Cache.Draw(Util.Cache.GetTexture(texture).Text2D, energyBarRect, Color.White);
                }

               

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }

        /// <summary>
        /// draw battery bar 
        /// </summary>
        public static void DrawBatteryBar()
        {
            //declare
            string texture = "BatteryBar0P";
  

            try
            {
                //draw battery bar only if nd auto scanner is on, it it's off player does not care about that
                if (AutoScannerON)
                {

                    #region get texture based on battery value

                    switch (BatteryLevel)
                    {
                        case 0:
                            {
                                texture = "BatteryBar0P";

                                break;
                            }
                        case 5:
                            {
                                texture = "BatteryBar5P";

                                break;
                            }
                        case 10:
                            {
                                texture = "BatteryBar10P";

                                break;
                            }
                        case 15:
                            {
                                texture = "BatteryBar15P";

                                break;
                            }
                        case 20:
                            {
                                texture = "BatteryBar20P";

                                break;
                            }
                        case 25:
                            {
                                texture = "BatteryBar20P";

                                break;
                            }
                        case 30:
                            {
                                texture = "BatteryBar30P";

                                break;
                            }
                        case 35:
                            {
                                texture = "BatteryBar35P";

                                break;
                            }
                        case 40:
                            {
                                texture = "BatteryBar40P";

                                break;
                            }
                        case 45:
                            {
                                texture = "BatteryBar45P";

                                break;
                            }
                        case 50:
                            {
                                texture = "BatteryBar50P";

                                break;
                            }
                        case 55:
                            {
                                texture = "BatteryBar55P";

                                break;
                            }
                        case 60:
                            {
                                texture = "BatteryBar60P";

                                break;
                            }
                        case 65:
                            {
                                texture = "BatteryBar65P";

                                break;
                            }
                        case 70:
                            {
                                texture = "BatteryBar70P";

                                break;
                            }
                        case 75:
                            {
                                texture = "BatteryBar75P";

                                break;
                            }
                        case 80:
                            {
                                texture = "BatteryBar80P";

                                break;
                            }
                        case 85:
                            {
                                texture = "BatteryBar85P";

                                break;
                            }
                        case 90:
                            {
                                texture = "BatteryBar90P";

                                break;
                            }
                        case 95:
                            {
                                texture = "BatteryBar95P";

                                break;
                            }
                        case 100:
                            {
                                texture = "BatteryBar100P";

                                break;
                            }


                    }
                    #endregion

                    //draw 
                    Util.Cache.Draw(Util.Cache.GetTexture(texture).Text2D, new int[] { ((int)Util.Cache.Avatar.CurrentPosition.X + Util.Cache.Avatar.Width) - WorldManager.WorldConfig.BatteryBarWidth, (int)Util.Cache.Avatar.CurrentPosition.Y, WorldManager.WorldConfig.BatteryBarWidth, Util.Cache.Avatar.Height }, Color.White);
                }
            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        /// <summary>
        /// draw energy bar 
        /// </summary>
        public static void DrawEnergyBar()
        {
            //declare
            string texture = "0P";
            Rectangle energyBarRect=new Rectangle((int)Util.Cache.Avatar.CurrentPosition.X + (Util.Cache.Avatar.Width * 2) + 5, (int)Util.Cache.Avatar.CurrentPosition.Y, WorldManager.WorldConfig.EnergyBarWidth, WorldManager.WorldConfig.EnergyBarHeight);

            try
            {
                #region get texture based on energy value

                switch (Energy)
                {
                    case 0:
                        {
                            texture = "0P";

                            break;
                        }
                    case 5:
                        {
                            texture = "5P";

                            break;
                        }
                    case 10:
                        {
                            texture = "10P";

                            break;
                        }
                    case 15:
                        {
                            texture = "15P";

                            break;
                        }
                    case 20:
                        {
                            texture = "20P";

                            break;
                        }
                    case 25:
                        {
                            texture = "25P";

                            break;
                        }
                    case 30:
                        {
                            texture = "30P";

                            break;
                        }
                    case 35:
                        {
                            texture = "35P";

                            break;
                        }
                    case 40:
                        {
                            texture = "40P";

                            break;
                        }
                    case 45:
                        {
                            texture = "45P";

                            break;
                        }
                    case 50:
                        {
                            texture = "50P";

                            break;
                        }
                    case 55:
                        {
                            texture = "55P";

                            break;
                        }
                    case 60:
                        {
                            texture = "60P";

                            break;
                        }
                    case 65:
                        {
                            texture = "65P";

                            break;
                        }
                    case 70:
                        {
                            texture = "70P";

                            break;
                        }
                    case 75:
                        {
                            texture = "75P";

                            break;
                        }
                    case 80:
                        {
                            texture = "80P";

                            break;
                        }
                    case 85:
                        {
                            texture = "85P";

                            break;
                        }
                    case 90:
                        {
                            texture = "90P";

                            break;
                        }
                    case 95:
                        {
                            texture = "95P";

                            break;
                        }
                    case 100:
                        {
                            texture = "100P";

                            break;
                        }


                }
                #endregion

                //draw (first check if energy bar can be drawn on the right side of avatar) -if no, draw on the left side
                if (IsEnergyBarOnTheScreen(energyBarRect))
                {
                    Util.Cache.Draw(Util.Cache.GetTexture(texture).Text2D, energyBarRect, Color.White);
                }
                else
                {
                    //draw on the left
                    energyBarRect.X = (int)Util.Cache.Avatar.CurrentPosition.X - (Util.Cache.Avatar.Width * 4) - 5;

                    Util.Cache.Draw(Util.Cache.GetTexture(texture).Text2D, energyBarRect, Color.White);
                }

            }
            catch (Exception ex)
            {
                Util.ErrorLogging.LogError(ex);
                return;
            }
        }


        #endregion




        #endregion



    }
}
